/* $Id: VBoxMPGaUtils.cpp $ */
/** @file
 * VirtualBox Windows Guest Mesa3D - Gallium driver interface for WDDM kernel mode driver.
 */

/*
 * Copyright (C) 2016-2020 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#include "CommonDef.h"
#include "asm.h"
#include "gallium/VBoxMPGaUtils.h"

void *GaMemAlloc(UINT32 cbSize)
{
    return ExAllocatePool2(POOL_FLAG_NON_PAGED, cbSize, SVGA_MEMTAG);
}

void *GaMemAllocZero(UINT32 cbSize)
{
    void *pvMem = GaMemAlloc(cbSize);
    if (pvMem)
        memset(pvMem, 0, cbSize);
    return pvMem;
}

void GaMemFree(void *pvMem)
{
    ExFreePoolWithTag(pvMem, SVGA_MEMTAG);
}

NTSTATUS GaIdAlloc(UINT32 *pu32Bits,
                   UINT32 cbBits,
                   UINT32 u32Limit,
                   UINT32 *pu32Id)
{
    /* Find the first zero bit. */
    const INT32 i32Id = ASMBitFirstClear(pu32Bits, cbBits * 8);
    if (0 <= i32Id && i32Id < (INT32)u32Limit)
    {
        ASMBitSet(pu32Bits, i32Id);
        *pu32Id = (UINT32)i32Id;
        return STATUS_SUCCESS;
    }

    return STATUS_INSUFFICIENT_RESOURCES;
}

NTSTATUS GaIdFree(UINT32 *pu32Bits,
                  UINT32 cbBits,
                  UINT32 u32Limit,
                  UINT32 u32Id)
{
    AssertReturn(u32Limit <= cbBits * 8, STATUS_INVALID_PARAMETER);
    AssertReturn(u32Id < u32Limit, STATUS_INVALID_PARAMETER);

    /* Clear the corresponding bit. */
    ASMBitClear(pu32Bits, (INT32)u32Id);

    return STATUS_SUCCESS;
}
